//
// File: FFTImplementationCallback.cpp
//
// MATLAB Coder version            : 5.4
// C/C++ source code generated on  : 23-Apr-2025 16:26:18
//

// Include Files
#include "FFTImplementationCallback.h"
#include "rt_nonfinite.h"
#include "coder_array.h"
#include <cmath>
#include <string.h>

// Function Definitions
//
// Arguments    : int nRows
//                ::coder::array<double, 2U> &costab
//                ::coder::array<double, 2U> &sintab
//                ::coder::array<double, 2U> &sintabinv
// Return Type  : void
//
namespace coder {
namespace internal {
void FFTImplementationCallback::b_generate_twiddle_tables(
    int nRows, ::coder::array<double, 2U> &costab,
    ::coder::array<double, 2U> &sintab, ::coder::array<double, 2U> &sintabinv)
{
  array<double, 2U> costab1q;
  double e;
  int i;
  int n;
  int nd2;
  e = 6.2831853071795862 / static_cast<double>(nRows);
  n = nRows / 2 / 2;
  costab1q.set_size(1, n + 1);
  costab1q[0] = 1.0;
  nd2 = n / 2 - 1;
  for (int k{0}; k <= nd2; k++) {
    costab1q[k + 1] = std::cos(e * (static_cast<double>(k) + 1.0));
  }
  i = nd2 + 2;
  nd2 = n - 1;
  for (int k{i}; k <= nd2; k++) {
    costab1q[k] = std::sin(e * static_cast<double>(n - k));
  }
  costab1q[n] = 0.0;
  n = costab1q.size(1) - 1;
  nd2 = (costab1q.size(1) - 1) << 1;
  costab.set_size(1, nd2 + 1);
  sintab.set_size(1, nd2 + 1);
  costab[0] = 1.0;
  sintab[0] = 0.0;
  sintabinv.set_size(1, nd2 + 1);
  for (int k{0}; k < n; k++) {
    sintabinv[k + 1] = costab1q[(n - k) - 1];
  }
  i = costab1q.size(1);
  for (int k{i}; k <= nd2; k++) {
    sintabinv[k] = costab1q[k - n];
  }
  for (int k{0}; k < n; k++) {
    costab[k + 1] = costab1q[k + 1];
    sintab[k + 1] = -costab1q[(n - k) - 1];
  }
  i = costab1q.size(1);
  for (int k{i}; k <= nd2; k++) {
    costab[k] = -costab1q[nd2 - k];
    sintab[k] = -costab1q[k - n];
  }
}

//
// Arguments    : const ::coder::array<double, 1U> &x
//                ::coder::array<creal_T, 1U> &y
//                int nrowsx
//                int nRows
//                int nfft
//                const ::coder::array<creal_T, 1U> &wwc
//                const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
//                const ::coder::array<double, 2U> &costabinv
//                const ::coder::array<double, 2U> &sintabinv
// Return Type  : void
//
void FFTImplementationCallback::doHalfLengthBluestein(
    const ::coder::array<double, 1U> &x, ::coder::array<creal_T, 1U> &y,
    int nrowsx, int nRows, int nfft, const ::coder::array<creal_T, 1U> &wwc,
    const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab,
    const ::coder::array<double, 2U> &costabinv,
    const ::coder::array<double, 2U> &sintabinv)
{
  array<creal_T, 1U> b_fv;
  array<creal_T, 1U> fv;
  array<creal_T, 1U> reconVar1;
  array<creal_T, 1U> reconVar2;
  array<creal_T, 1U> ytmp;
  array<double, 2U> a__1;
  array<double, 2U> costable;
  array<double, 2U> hcostabinv;
  array<double, 2U> hsintab;
  array<double, 2U> hsintabinv;
  array<double, 2U> sintable;
  array<int, 2U> wrapIndex;
  double a_im;
  double a_re;
  double b_im;
  double b_re;
  double z_tmp;
  int b_i;
  int b_re_tmp;
  int hnRows;
  int i;
  int u0;
  boolean_T nxeven;
  hnRows = nRows / 2;
  ytmp.set_size(hnRows);
  if (hnRows > nrowsx) {
    ytmp.set_size(hnRows);
    for (i = 0; i < hnRows; i++) {
      ytmp[i].re = 0.0;
      ytmp[i].im = 0.0;
    }
  }
  if ((x.size(0) & 1) == 0) {
    nxeven = true;
    u0 = x.size(0);
  } else if (x.size(0) >= nRows) {
    nxeven = true;
    u0 = nRows;
  } else {
    nxeven = false;
    u0 = x.size(0) - 1;
  }
  if (u0 > nRows) {
    u0 = nRows;
  }
  FFTImplementationCallback::b_generate_twiddle_tables(nRows << 1, costable,
                                                       sintable, a__1);
  FFTImplementationCallback::get_half_twiddle_tables(costab, sintab, costabinv,
                                                     sintabinv, a__1, hsintab,
                                                     hcostabinv, hsintabinv);
  reconVar1.set_size(hnRows);
  reconVar2.set_size(hnRows);
  wrapIndex.set_size(1, hnRows);
  for (b_i = 0; b_i < hnRows; b_i++) {
    i = b_i << 1;
    z_tmp = sintable[i];
    a_re = costable[i];
    reconVar1[b_i].re = z_tmp + 1.0;
    reconVar1[b_i].im = -a_re;
    reconVar2[b_i].re = 1.0 - z_tmp;
    reconVar2[b_i].im = a_re;
    if (b_i + 1 != 1) {
      wrapIndex[b_i] = (hnRows - b_i) + 1;
    } else {
      wrapIndex[0] = 1;
    }
  }
  z_tmp = static_cast<double>(u0) / 2.0;
  i = static_cast<int>(z_tmp);
  for (int k1{0}; k1 < i; k1++) {
    b_i = (hnRows + k1) - 1;
    a_re = wwc[b_i].re;
    a_im = wwc[b_i].im;
    b_re_tmp = k1 << 1;
    b_re = x[b_re_tmp];
    b_im = x[b_re_tmp + 1];
    ytmp[k1].re = a_re * b_re + a_im * b_im;
    ytmp[k1].im = a_re * b_im - a_im * b_re;
  }
  if (!nxeven) {
    b_i = (hnRows + static_cast<int>(z_tmp)) - 1;
    a_re = wwc[b_i].re;
    a_im = wwc[b_i].im;
    b_re = x[static_cast<int>(z_tmp) << 1];
    ytmp[static_cast<int>(z_tmp)].re = a_re * b_re + a_im * 0.0;
    ytmp[static_cast<int>(z_tmp)].im = a_re * 0.0 - a_im * b_re;
    if (static_cast<int>(z_tmp) + 2 <= hnRows) {
      i = static_cast<int>(static_cast<double>(u0) / 2.0) + 2;
      for (b_i = i; b_i <= hnRows; b_i++) {
        ytmp[b_i - 1].re = 0.0;
        ytmp[b_i - 1].im = 0.0;
      }
    }
  } else if (static_cast<int>(z_tmp) + 1 <= hnRows) {
    i = static_cast<int>(static_cast<double>(u0) / 2.0) + 1;
    for (b_i = i; b_i <= hnRows; b_i++) {
      ytmp[b_i - 1].re = 0.0;
      ytmp[b_i - 1].im = 0.0;
    }
  }
  b_i = static_cast<int>(static_cast<double>(nfft) / 2.0);
  FFTImplementationCallback::r2br_r2dit_trig_impl(ytmp, b_i, a__1, hsintab, fv);
  FFTImplementationCallback::r2br_r2dit_trig_impl(wwc, b_i, a__1, hsintab,
                                                  b_fv);
  b_fv.set_size(fv.size(0));
  b_re_tmp = fv.size(0);
  for (i = 0; i < b_re_tmp; i++) {
    z_tmp = fv[i].re;
    a_re = b_fv[i].im;
    a_im = fv[i].im;
    b_re = b_fv[i].re;
    b_fv[i].re = z_tmp * b_re - a_im * a_re;
    b_fv[i].im = z_tmp * a_re + a_im * b_re;
  }
  FFTImplementationCallback::r2br_r2dit_trig_impl(b_fv, b_i, hcostabinv,
                                                  hsintabinv, fv);
  if (fv.size(0) > 1) {
    z_tmp = 1.0 / static_cast<double>(fv.size(0));
    b_re_tmp = fv.size(0);
    for (i = 0; i < b_re_tmp; i++) {
      fv[i].re = z_tmp * fv[i].re;
      fv[i].im = z_tmp * fv[i].im;
    }
  }
  i = wwc.size(0);
  for (b_re_tmp = hnRows; b_re_tmp <= i; b_re_tmp++) {
    z_tmp = wwc[b_re_tmp - 1].re;
    a_re = fv[b_re_tmp - 1].im;
    a_im = wwc[b_re_tmp - 1].im;
    b_re = fv[b_re_tmp - 1].re;
    b_i = b_re_tmp - hnRows;
    ytmp[b_i].re = z_tmp * b_re + a_im * a_re;
    ytmp[b_i].im = z_tmp * a_re - a_im * b_re;
  }
  for (b_i = 0; b_i < hnRows; b_i++) {
    double b_ytmp_re_tmp;
    double ytmp_im_tmp;
    double ytmp_re_tmp;
    i = wrapIndex[b_i];
    z_tmp = ytmp[b_i].re;
    a_re = reconVar1[b_i].im;
    a_im = ytmp[b_i].im;
    b_re = reconVar1[b_i].re;
    b_im = ytmp[i - 1].re;
    ytmp_im_tmp = -ytmp[i - 1].im;
    ytmp_re_tmp = reconVar2[b_i].im;
    b_ytmp_re_tmp = reconVar2[b_i].re;
    y[b_i].re = 0.5 * ((z_tmp * b_re - a_im * a_re) +
                       (b_im * b_ytmp_re_tmp - ytmp_im_tmp * ytmp_re_tmp));
    y[b_i].im = 0.5 * ((z_tmp * a_re + a_im * b_re) +
                       (b_im * ytmp_re_tmp + ytmp_im_tmp * b_ytmp_re_tmp));
    i = hnRows + b_i;
    y[i].re = 0.5 * ((z_tmp * b_ytmp_re_tmp - a_im * ytmp_re_tmp) +
                     (b_im * b_re - ytmp_im_tmp * a_re));
    y[i].im = 0.5 * ((z_tmp * ytmp_re_tmp + a_im * b_ytmp_re_tmp) +
                     (b_im * a_re + ytmp_im_tmp * b_re));
  }
}

//
// Arguments    : int nRowsM1
//                int nfftLen
//                ::coder::array<int, 1U> &bitrevIndex
// Return Type  : void
//
void FFTImplementationCallback::get_bitrevIndex(
    int nRowsM1, int nfftLen, ::coder::array<int, 1U> &bitrevIndex)
{
  int iy;
  int ju;
  ju = 0;
  iy = 1;
  bitrevIndex.set_size(nfftLen);
  for (int b_j1{0}; b_j1 < nfftLen; b_j1++) {
    bitrevIndex[b_j1] = 0;
  }
  for (int b_j1{0}; b_j1 < nRowsM1; b_j1++) {
    boolean_T tst;
    bitrevIndex[b_j1] = iy;
    iy = nfftLen;
    tst = true;
    while (tst) {
      iy >>= 1;
      ju ^= iy;
      tst = ((ju & iy) == 0);
    }
    iy = ju + 1;
  }
  bitrevIndex[nRowsM1] = iy;
}

//
// Arguments    : const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
//                const ::coder::array<double, 2U> &costabinv
//                const ::coder::array<double, 2U> &sintabinv
//                ::coder::array<double, 2U> &hcostab
//                ::coder::array<double, 2U> &hsintab
//                ::coder::array<double, 2U> &hcostabinv
//                ::coder::array<double, 2U> &hsintabinv
// Return Type  : void
//
void FFTImplementationCallback::get_half_twiddle_tables(
    const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab,
    const ::coder::array<double, 2U> &costabinv,
    const ::coder::array<double, 2U> &sintabinv,
    ::coder::array<double, 2U> &hcostab, ::coder::array<double, 2U> &hsintab,
    ::coder::array<double, 2U> &hcostabinv,
    ::coder::array<double, 2U> &hsintabinv)
{
  int hszCostab;
  hszCostab = costab.size(1) / 2;
  hcostab.set_size(1, hszCostab);
  hsintab.set_size(1, hszCostab);
  hcostabinv.set_size(1, hszCostab);
  hsintabinv.set_size(1, hszCostab);
  for (int i{0}; i < hszCostab; i++) {
    int hcostab_tmp;
    hcostab_tmp = ((i + 1) << 1) - 2;
    hcostab[i] = costab[hcostab_tmp];
    hsintab[i] = sintab[hcostab_tmp];
    hcostabinv[i] = costabinv[hcostab_tmp];
    hsintabinv[i] = sintabinv[hcostab_tmp];
  }
}

//
// Arguments    : ::coder::array<creal_T, 1U> &y
//                const ::coder::array<creal_T, 1U> &reconVar1
//                const ::coder::array<creal_T, 1U> &reconVar2
//                const ::coder::array<int, 2U> &wrapIndex
//                int hnRows
// Return Type  : void
//
void FFTImplementationCallback::getback_radix2_fft(
    ::coder::array<creal_T, 1U> &y,
    const ::coder::array<creal_T, 1U> &reconVar1,
    const ::coder::array<creal_T, 1U> &reconVar2,
    const ::coder::array<int, 2U> &wrapIndex, int hnRows)
{
  double b_temp1_re_tmp;
  double b_temp2_re_tmp;
  double b_y_re_tmp;
  double c_temp1_re_tmp;
  double c_temp2_re_tmp;
  double c_y_re_tmp;
  double d_y_re_tmp;
  double temp1_im_tmp;
  double temp1_re_tmp;
  double y_re_tmp;
  int b_i;
  int iterVar;
  iterVar = hnRows / 2;
  temp1_re_tmp = y[0].re;
  temp1_im_tmp = y[0].im;
  y[0].re =
      0.5 *
      ((temp1_re_tmp * reconVar1[0].re - temp1_im_tmp * reconVar1[0].im) +
       (temp1_re_tmp * reconVar2[0].re - -temp1_im_tmp * reconVar2[0].im));
  y[0].im =
      0.5 *
      ((temp1_re_tmp * reconVar1[0].im + temp1_im_tmp * reconVar1[0].re) +
       (temp1_re_tmp * reconVar2[0].im + -temp1_im_tmp * reconVar2[0].re));
  y[hnRows].re =
      0.5 *
      ((temp1_re_tmp * reconVar2[0].re - temp1_im_tmp * reconVar2[0].im) +
       (temp1_re_tmp * reconVar1[0].re - -temp1_im_tmp * reconVar1[0].im));
  y[hnRows].im =
      0.5 *
      ((temp1_re_tmp * reconVar2[0].im + temp1_im_tmp * reconVar2[0].re) +
       (temp1_re_tmp * reconVar1[0].im + -temp1_im_tmp * reconVar1[0].re));
  for (int i{2}; i <= iterVar; i++) {
    double temp2_im_tmp;
    double temp2_re_tmp;
    int i1;
    temp1_re_tmp = y[i - 1].re;
    temp1_im_tmp = y[i - 1].im;
    b_i = wrapIndex[i - 1];
    temp2_re_tmp = y[b_i - 1].re;
    temp2_im_tmp = y[b_i - 1].im;
    y_re_tmp = reconVar1[i - 1].im;
    b_y_re_tmp = reconVar1[i - 1].re;
    c_y_re_tmp = reconVar2[i - 1].im;
    d_y_re_tmp = reconVar2[i - 1].re;
    y[i - 1].re =
        0.5 * ((temp1_re_tmp * b_y_re_tmp - temp1_im_tmp * y_re_tmp) +
               (temp2_re_tmp * d_y_re_tmp - -temp2_im_tmp * c_y_re_tmp));
    y[i - 1].im =
        0.5 * ((temp1_re_tmp * y_re_tmp + temp1_im_tmp * b_y_re_tmp) +
               (temp2_re_tmp * c_y_re_tmp + -temp2_im_tmp * d_y_re_tmp));
    i1 = (hnRows + i) - 1;
    y[i1].re = 0.5 * ((temp1_re_tmp * d_y_re_tmp - temp1_im_tmp * c_y_re_tmp) +
                      (temp2_re_tmp * b_y_re_tmp - -temp2_im_tmp * y_re_tmp));
    y[i1].im = 0.5 * ((temp1_re_tmp * c_y_re_tmp + temp1_im_tmp * d_y_re_tmp) +
                      (temp2_re_tmp * y_re_tmp + -temp2_im_tmp * b_y_re_tmp));
    c_temp2_re_tmp = reconVar1[b_i - 1].im;
    b_temp2_re_tmp = reconVar1[b_i - 1].re;
    b_temp1_re_tmp = reconVar2[b_i - 1].im;
    c_temp1_re_tmp = reconVar2[b_i - 1].re;
    y[b_i - 1].re =
        0.5 *
        ((temp2_re_tmp * b_temp2_re_tmp - temp2_im_tmp * c_temp2_re_tmp) +
         (temp1_re_tmp * c_temp1_re_tmp - -temp1_im_tmp * b_temp1_re_tmp));
    y[b_i - 1].im =
        0.5 *
        ((temp2_re_tmp * c_temp2_re_tmp + temp2_im_tmp * b_temp2_re_tmp) +
         (temp1_re_tmp * b_temp1_re_tmp + -temp1_im_tmp * c_temp1_re_tmp));
    b_i = (b_i + hnRows) - 1;
    y[b_i].re =
        0.5 *
        ((temp2_re_tmp * c_temp1_re_tmp - temp2_im_tmp * b_temp1_re_tmp) +
         (temp1_re_tmp * b_temp2_re_tmp - -temp1_im_tmp * c_temp2_re_tmp));
    y[b_i].im =
        0.5 *
        ((temp2_re_tmp * b_temp1_re_tmp + temp2_im_tmp * c_temp1_re_tmp) +
         (temp1_re_tmp * c_temp2_re_tmp + -temp1_im_tmp * b_temp2_re_tmp));
  }
  if (iterVar != 0) {
    temp1_re_tmp = y[iterVar].re;
    temp1_im_tmp = y[iterVar].im;
    y_re_tmp = reconVar1[iterVar].im;
    b_y_re_tmp = reconVar1[iterVar].re;
    c_y_re_tmp = reconVar2[iterVar].im;
    d_y_re_tmp = reconVar2[iterVar].re;
    b_temp2_re_tmp = temp1_re_tmp * d_y_re_tmp;
    b_temp1_re_tmp = temp1_re_tmp * b_y_re_tmp;
    y[iterVar].re = 0.5 * ((b_temp1_re_tmp - temp1_im_tmp * y_re_tmp) +
                           (b_temp2_re_tmp - -temp1_im_tmp * c_y_re_tmp));
    c_temp1_re_tmp = temp1_re_tmp * c_y_re_tmp;
    c_temp2_re_tmp = temp1_re_tmp * y_re_tmp;
    y[iterVar].im = 0.5 * ((c_temp2_re_tmp + temp1_im_tmp * b_y_re_tmp) +
                           (c_temp1_re_tmp + -temp1_im_tmp * d_y_re_tmp));
    b_i = hnRows + iterVar;
    y[b_i].re = 0.5 * ((b_temp2_re_tmp - temp1_im_tmp * c_y_re_tmp) +
                       (b_temp1_re_tmp - -temp1_im_tmp * y_re_tmp));
    y[b_i].im = 0.5 * ((c_temp1_re_tmp + temp1_im_tmp * d_y_re_tmp) +
                       (c_temp2_re_tmp + -temp1_im_tmp * b_y_re_tmp));
  }
}

//
// Arguments    : double x
//                ::coder::array<creal_T, 1U> &y
//                int nRows
//                int nfft
//                const ::coder::array<creal_T, 1U> &wwc
//                const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
//                const ::coder::array<double, 2U> &costabinv
//                const ::coder::array<double, 2U> &sintabinv
// Return Type  : void
//
void FFTImplementationCallback::doHalfLengthBluestein(
    double x, ::coder::array<creal_T, 1U> &y, int nRows, int nfft,
    const ::coder::array<creal_T, 1U> &wwc,
    const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab,
    const ::coder::array<double, 2U> &costabinv,
    const ::coder::array<double, 2U> &sintabinv)
{
  array<creal_T, 1U> b_fv;
  array<creal_T, 1U> fv;
  array<creal_T, 1U> reconVar1;
  array<creal_T, 1U> reconVar2;
  array<creal_T, 1U> ytmp;
  array<double, 2U> a__1;
  array<double, 2U> costable;
  array<double, 2U> hcostabinv;
  array<double, 2U> hsintab;
  array<double, 2U> hsintabinv;
  array<double, 2U> sintable;
  array<int, 2U> wrapIndex;
  double a_im;
  double a_re;
  double b_re_tmp;
  double re_tmp;
  double z_tmp;
  int b_i;
  int hnRows;
  int i;
  int minHnrowsNx;
  boolean_T nxeven;
  hnRows = nRows / 2;
  ytmp.set_size(hnRows);
  if (hnRows > 1) {
    ytmp.set_size(hnRows);
    for (i = 0; i < hnRows; i++) {
      ytmp[i].re = 0.0;
      ytmp[i].im = 0.0;
    }
  }
  if (nRows <= 1) {
    nxeven = true;
    minHnrowsNx = 1;
  } else {
    nxeven = false;
    minHnrowsNx = 0;
  }
  FFTImplementationCallback::b_generate_twiddle_tables(nRows << 1, costable,
                                                       sintable, a__1);
  FFTImplementationCallback::get_half_twiddle_tables(costab, sintab, costabinv,
                                                     sintabinv, a__1, hsintab,
                                                     hcostabinv, hsintabinv);
  reconVar1.set_size(hnRows);
  reconVar2.set_size(hnRows);
  wrapIndex.set_size(1, hnRows);
  for (b_i = 0; b_i < hnRows; b_i++) {
    i = b_i << 1;
    re_tmp = sintable[i];
    b_re_tmp = costable[i];
    reconVar1[b_i].re = re_tmp + 1.0;
    reconVar1[b_i].im = -b_re_tmp;
    reconVar2[b_i].re = 1.0 - re_tmp;
    reconVar2[b_i].im = b_re_tmp;
    if (b_i + 1 != 1) {
      wrapIndex[b_i] = (hnRows - b_i) + 1;
    } else {
      wrapIndex[0] = 1;
    }
  }
  z_tmp = static_cast<double>(minHnrowsNx) / 2.0;
  if (static_cast<int>(z_tmp) - 1 >= 0) {
    re_tmp = wwc[hnRows - 1].re;
    b_re_tmp = wwc[hnRows - 1].im;
    re_tmp *= x;
    b_re_tmp *= x;
    ytmp[0].re = re_tmp + b_re_tmp;
    ytmp[0].im = re_tmp - b_re_tmp;
  }
  if (!nxeven) {
    b_i = (hnRows + static_cast<int>(z_tmp)) - 1;
    a_re = wwc[b_i].re;
    a_im = wwc[b_i].im;
    ytmp[static_cast<int>(static_cast<double>(minHnrowsNx) / 2.0)].re =
        a_re * x + a_im * 0.0;
    ytmp[static_cast<int>(static_cast<double>(minHnrowsNx) / 2.0)].im =
        a_re * 0.0 - a_im * x;
    if (static_cast<int>(z_tmp) + 2 <= hnRows) {
      i = static_cast<int>(static_cast<double>(minHnrowsNx) / 2.0) + 2;
      for (b_i = i; b_i <= hnRows; b_i++) {
        ytmp[b_i - 1].re = 0.0;
        ytmp[b_i - 1].im = 0.0;
      }
    }
  } else if (static_cast<int>(z_tmp) + 1 <= hnRows) {
    i = static_cast<int>(static_cast<double>(minHnrowsNx) / 2.0) + 1;
    for (b_i = i; b_i <= hnRows; b_i++) {
      ytmp[b_i - 1].re = 0.0;
      ytmp[b_i - 1].im = 0.0;
    }
  }
  b_i = static_cast<int>(static_cast<double>(nfft) / 2.0);
  FFTImplementationCallback::r2br_r2dit_trig_impl(ytmp, b_i, a__1, hsintab, fv);
  FFTImplementationCallback::r2br_r2dit_trig_impl(wwc, b_i, a__1, hsintab,
                                                  b_fv);
  b_fv.set_size(fv.size(0));
  minHnrowsNx = fv.size(0);
  for (i = 0; i < minHnrowsNx; i++) {
    a_re = fv[i].re;
    a_im = b_fv[i].im;
    re_tmp = fv[i].im;
    b_re_tmp = b_fv[i].re;
    b_fv[i].re = a_re * b_re_tmp - re_tmp * a_im;
    b_fv[i].im = a_re * a_im + re_tmp * b_re_tmp;
  }
  FFTImplementationCallback::r2br_r2dit_trig_impl(b_fv, b_i, hcostabinv,
                                                  hsintabinv, fv);
  if (fv.size(0) > 1) {
    a_re = 1.0 / static_cast<double>(fv.size(0));
    minHnrowsNx = fv.size(0);
    for (i = 0; i < minHnrowsNx; i++) {
      fv[i].re = a_re * fv[i].re;
      fv[i].im = a_re * fv[i].im;
    }
  }
  i = wwc.size(0);
  for (minHnrowsNx = hnRows; minHnrowsNx <= i; minHnrowsNx++) {
    re_tmp = wwc[minHnrowsNx - 1].re;
    b_re_tmp = fv[minHnrowsNx - 1].im;
    a_re = wwc[minHnrowsNx - 1].im;
    a_im = fv[minHnrowsNx - 1].re;
    b_i = minHnrowsNx - hnRows;
    ytmp[b_i].re = re_tmp * a_im + a_re * b_re_tmp;
    ytmp[b_i].im = re_tmp * b_re_tmp - a_re * a_im;
  }
  for (b_i = 0; b_i < hnRows; b_i++) {
    double b_ytmp_re_tmp;
    double ytmp_im_tmp;
    double ytmp_re_tmp;
    i = wrapIndex[b_i];
    a_re = ytmp[b_i].re;
    a_im = reconVar1[b_i].im;
    re_tmp = ytmp[b_i].im;
    b_re_tmp = reconVar1[b_i].re;
    z_tmp = ytmp[i - 1].re;
    ytmp_im_tmp = -ytmp[i - 1].im;
    ytmp_re_tmp = reconVar2[b_i].im;
    b_ytmp_re_tmp = reconVar2[b_i].re;
    y[b_i].re = 0.5 * ((a_re * b_re_tmp - re_tmp * a_im) +
                       (z_tmp * b_ytmp_re_tmp - ytmp_im_tmp * ytmp_re_tmp));
    y[b_i].im = 0.5 * ((a_re * a_im + re_tmp * b_re_tmp) +
                       (z_tmp * ytmp_re_tmp + ytmp_im_tmp * b_ytmp_re_tmp));
    i = hnRows + b_i;
    y[i].re = 0.5 * ((a_re * b_ytmp_re_tmp - re_tmp * ytmp_re_tmp) +
                     (z_tmp * b_re_tmp - ytmp_im_tmp * a_im));
    y[i].im = 0.5 * ((a_re * ytmp_re_tmp + re_tmp * b_ytmp_re_tmp) +
                     (z_tmp * a_im + ytmp_im_tmp * b_re_tmp));
  }
}

//
// Arguments    : double x
//                ::coder::array<creal_T, 1U> &y
//                int unsigned_nRows
//                const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
// Return Type  : void
//
void FFTImplementationCallback::doHalfLengthRadix2(
    double x, ::coder::array<creal_T, 1U> &y, int unsigned_nRows,
    const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab)
{
  array<creal_T, 1U> reconVar1;
  array<creal_T, 1U> reconVar2;
  array<double, 2U> hcostab;
  array<double, 2U> hsintab;
  array<int, 2U> wrapIndex;
  array<int, 1U> bitrevIndex;
  double temp_im;
  double temp_im_tmp;
  double z;
  int hszCostab;
  int i;
  int iDelta2;
  int istart;
  int k;
  int nRows;
  int nRowsD2;
  boolean_T nxeven;
  nRows = unsigned_nRows / 2;
  istart = nRows - 2;
  nRowsD2 = nRows / 2;
  k = nRowsD2 / 2;
  hszCostab = costab.size(1) / 2;
  hcostab.set_size(1, hszCostab);
  hsintab.set_size(1, hszCostab);
  for (i = 0; i < hszCostab; i++) {
    iDelta2 = ((i + 1) << 1) - 2;
    hcostab[i] = costab[iDelta2];
    hsintab[i] = sintab[iDelta2];
  }
  reconVar1.set_size(nRows);
  reconVar2.set_size(nRows);
  wrapIndex.set_size(1, nRows);
  for (i = 0; i < nRows; i++) {
    temp_im = sintab[i];
    temp_im_tmp = costab[i];
    reconVar1[i].re = temp_im + 1.0;
    reconVar1[i].im = -temp_im_tmp;
    reconVar2[i].re = 1.0 - temp_im;
    reconVar2[i].im = temp_im_tmp;
    if (i + 1 != 1) {
      wrapIndex[i] = (nRows - i) + 1;
    } else {
      wrapIndex[0] = 1;
    }
  }
  z = static_cast<double>(unsigned_nRows) / 2.0;
  hszCostab = y.size(0);
  if (hszCostab > nRows) {
    hszCostab = nRows;
  }
  FFTImplementationCallback::get_bitrevIndex(hszCostab - 1, static_cast<int>(z),
                                             bitrevIndex);
  if (unsigned_nRows <= 1) {
    nxeven = true;
    hszCostab = 1;
  } else {
    nxeven = false;
    hszCostab = 0;
  }
  temp_im = static_cast<double>(hszCostab) / 2.0;
  hszCostab = static_cast<int>(temp_im);
  for (i = 0; i < hszCostab; i++) {
    y[bitrevIndex[0] - 1].re = x;
    y[bitrevIndex[0] - 1].im = x;
  }
  if (!nxeven) {
    hszCostab = bitrevIndex[static_cast<int>(temp_im)] - 1;
    y[hszCostab].re = x;
    y[hszCostab].im = 0.0;
  }
  if (nRows > 1) {
    for (i = 0; i <= istart; i += 2) {
      temp_im = y[i + 1].re;
      temp_im_tmp = y[i + 1].im;
      y[i + 1].re = y[i].re - temp_im;
      y[i + 1].im = y[i].im - y[i + 1].im;
      y[i].re = y[i].re + temp_im;
      y[i].im = y[i].im + temp_im_tmp;
    }
  }
  hszCostab = 2;
  iDelta2 = 4;
  nRows = ((k - 1) << 2) + 1;
  while (k > 0) {
    double temp_re;
    int temp_re_tmp;
    for (i = 0; i < nRows; i += iDelta2) {
      temp_re_tmp = i + hszCostab;
      temp_re = y[temp_re_tmp].re;
      temp_im = y[temp_re_tmp].im;
      y[temp_re_tmp].re = y[i].re - temp_re;
      y[temp_re_tmp].im = y[i].im - temp_im;
      y[i].re = y[i].re + temp_re;
      y[i].im = y[i].im + temp_im;
    }
    istart = 1;
    for (int j{k}; j < nRowsD2; j += k) {
      double twid_im;
      double twid_re;
      int ihi;
      twid_re = hcostab[j];
      twid_im = hsintab[j];
      i = istart;
      ihi = istart + nRows;
      while (i < ihi) {
        temp_re_tmp = i + hszCostab;
        temp_im = y[temp_re_tmp].im;
        temp_im_tmp = y[temp_re_tmp].re;
        temp_re = twid_re * temp_im_tmp - twid_im * temp_im;
        temp_im = twid_re * temp_im + twid_im * temp_im_tmp;
        y[temp_re_tmp].re = y[i].re - temp_re;
        y[temp_re_tmp].im = y[i].im - temp_im;
        y[i].re = y[i].re + temp_re;
        y[i].im = y[i].im + temp_im;
        i += iDelta2;
      }
      istart++;
    }
    k /= 2;
    hszCostab = iDelta2;
    iDelta2 += iDelta2;
    nRows -= hszCostab;
  }
  FFTImplementationCallback::getback_radix2_fft(y, reconVar1, reconVar2,
                                                wrapIndex, static_cast<int>(z));
}

//
// Arguments    : const ::coder::array<double, 1U> &x
//                ::coder::array<creal_T, 1U> &y
//                int unsigned_nRows
//                const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
// Return Type  : void
//
void FFTImplementationCallback::doHalfLengthRadix2(
    const ::coder::array<double, 1U> &x, ::coder::array<creal_T, 1U> &y,
    int unsigned_nRows, const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab)
{
  array<creal_T, 1U> reconVar1;
  array<creal_T, 1U> reconVar2;
  array<double, 2U> hcostab;
  array<double, 2U> hsintab;
  array<int, 2U> wrapIndex;
  array<int, 1U> bitrevIndex;
  double temp_im;
  double temp_im_tmp;
  double z;
  int hszCostab;
  int i;
  int iDelta2;
  int istart;
  int k;
  int nRows;
  int nRowsD2;
  boolean_T nxeven;
  nRows = unsigned_nRows / 2;
  istart = nRows - 2;
  nRowsD2 = nRows / 2;
  k = nRowsD2 / 2;
  hszCostab = costab.size(1) / 2;
  hcostab.set_size(1, hszCostab);
  hsintab.set_size(1, hszCostab);
  for (i = 0; i < hszCostab; i++) {
    iDelta2 = ((i + 1) << 1) - 2;
    hcostab[i] = costab[iDelta2];
    hsintab[i] = sintab[iDelta2];
  }
  reconVar1.set_size(nRows);
  reconVar2.set_size(nRows);
  wrapIndex.set_size(1, nRows);
  for (i = 0; i < nRows; i++) {
    temp_im = sintab[i];
    temp_im_tmp = costab[i];
    reconVar1[i].re = temp_im + 1.0;
    reconVar1[i].im = -temp_im_tmp;
    reconVar2[i].re = 1.0 - temp_im;
    reconVar2[i].im = temp_im_tmp;
    if (i + 1 != 1) {
      wrapIndex[i] = (nRows - i) + 1;
    } else {
      wrapIndex[0] = 1;
    }
  }
  z = static_cast<double>(unsigned_nRows) / 2.0;
  hszCostab = y.size(0);
  if (hszCostab > nRows) {
    hszCostab = nRows;
  }
  FFTImplementationCallback::get_bitrevIndex(hszCostab - 1, static_cast<int>(z),
                                             bitrevIndex);
  if ((x.size(0) & 1) == 0) {
    nxeven = true;
    hszCostab = x.size(0);
  } else if (x.size(0) >= unsigned_nRows) {
    nxeven = true;
    hszCostab = unsigned_nRows;
  } else {
    nxeven = false;
    hszCostab = x.size(0) - 1;
  }
  if (hszCostab > unsigned_nRows) {
    hszCostab = unsigned_nRows;
  }
  temp_im = static_cast<double>(hszCostab) / 2.0;
  hszCostab = static_cast<int>(temp_im);
  for (i = 0; i < hszCostab; i++) {
    iDelta2 = i << 1;
    y[bitrevIndex[i] - 1].re = x[iDelta2];
    y[bitrevIndex[i] - 1].im = x[iDelta2 + 1];
  }
  if (!nxeven) {
    hszCostab = bitrevIndex[static_cast<int>(temp_im)] - 1;
    y[hszCostab].re = x[static_cast<int>(temp_im) << 1];
    y[hszCostab].im = 0.0;
  }
  if (nRows > 1) {
    for (i = 0; i <= istart; i += 2) {
      temp_im = y[i + 1].re;
      temp_im_tmp = y[i + 1].im;
      y[i + 1].re = y[i].re - temp_im;
      y[i + 1].im = y[i].im - y[i + 1].im;
      y[i].re = y[i].re + temp_im;
      y[i].im = y[i].im + temp_im_tmp;
    }
  }
  hszCostab = 2;
  iDelta2 = 4;
  nRows = ((k - 1) << 2) + 1;
  while (k > 0) {
    double temp_re;
    int temp_re_tmp;
    for (i = 0; i < nRows; i += iDelta2) {
      temp_re_tmp = i + hszCostab;
      temp_re = y[temp_re_tmp].re;
      temp_im = y[temp_re_tmp].im;
      y[temp_re_tmp].re = y[i].re - temp_re;
      y[temp_re_tmp].im = y[i].im - temp_im;
      y[i].re = y[i].re + temp_re;
      y[i].im = y[i].im + temp_im;
    }
    istart = 1;
    for (int j{k}; j < nRowsD2; j += k) {
      double twid_im;
      double twid_re;
      int ihi;
      twid_re = hcostab[j];
      twid_im = hsintab[j];
      i = istart;
      ihi = istart + nRows;
      while (i < ihi) {
        temp_re_tmp = i + hszCostab;
        temp_im = y[temp_re_tmp].im;
        temp_im_tmp = y[temp_re_tmp].re;
        temp_re = twid_re * temp_im_tmp - twid_im * temp_im;
        temp_im = twid_re * temp_im + twid_im * temp_im_tmp;
        y[temp_re_tmp].re = y[i].re - temp_re;
        y[temp_re_tmp].im = y[i].im - temp_im;
        y[i].re = y[i].re + temp_re;
        y[i].im = y[i].im + temp_im;
        i += iDelta2;
      }
      istart++;
    }
    k /= 2;
    hszCostab = iDelta2;
    iDelta2 += iDelta2;
    nRows -= hszCostab;
  }
  FFTImplementationCallback::getback_radix2_fft(y, reconVar1, reconVar2,
                                                wrapIndex, static_cast<int>(z));
}

//
// Arguments    : const ::coder::array<double, 1U> &x
//                int n2blue
//                int nfft
//                const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
//                const ::coder::array<double, 2U> &sintabinv
//                ::coder::array<creal_T, 1U> &y
// Return Type  : void
//
void FFTImplementationCallback::dobluesteinfft(
    const ::coder::array<double, 1U> &x, int n2blue, int nfft,
    const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab,
    const ::coder::array<double, 2U> &sintabinv, ::coder::array<creal_T, 1U> &y)
{
  array<creal_T, 1U> b_fv;
  array<creal_T, 1U> fv;
  array<creal_T, 1U> wwc;
  double nt_im;
  double nt_re;
  int i;
  int minNrowsNx;
  int nInt2m1;
  if ((nfft != 1) && ((nfft & 1) == 0)) {
    int nInt2;
    int nRows;
    int rt;
    nRows = nfft / 2;
    nInt2m1 = (nRows + nRows) - 1;
    wwc.set_size(nInt2m1);
    rt = 0;
    wwc[nRows - 1].re = 1.0;
    wwc[nRows - 1].im = 0.0;
    nInt2 = nRows << 1;
    for (int k{0}; k <= nRows - 2; k++) {
      minNrowsNx = ((k + 1) << 1) - 1;
      if (nInt2 - rt <= minNrowsNx) {
        rt += minNrowsNx - nInt2;
      } else {
        rt += minNrowsNx;
      }
      nt_im = -3.1415926535897931 * static_cast<double>(rt) /
              static_cast<double>(nRows);
      if (nt_im == 0.0) {
        nt_re = 1.0;
        nt_im = 0.0;
      } else {
        nt_re = std::cos(nt_im);
        nt_im = std::sin(nt_im);
      }
      i = (nRows - k) - 2;
      wwc[i].re = nt_re;
      wwc[i].im = -nt_im;
    }
    i = nInt2m1 - 1;
    for (int k{i}; k >= nRows; k--) {
      wwc[k] = wwc[(nInt2m1 - k) - 1];
    }
  } else {
    int nInt2;
    int rt;
    nInt2m1 = (nfft + nfft) - 1;
    wwc.set_size(nInt2m1);
    rt = 0;
    wwc[nfft - 1].re = 1.0;
    wwc[nfft - 1].im = 0.0;
    nInt2 = nfft << 1;
    for (int k{0}; k <= nfft - 2; k++) {
      minNrowsNx = ((k + 1) << 1) - 1;
      if (nInt2 - rt <= minNrowsNx) {
        rt += minNrowsNx - nInt2;
      } else {
        rt += minNrowsNx;
      }
      nt_im = -3.1415926535897931 * static_cast<double>(rt) /
              static_cast<double>(nfft);
      if (nt_im == 0.0) {
        nt_re = 1.0;
        nt_im = 0.0;
      } else {
        nt_re = std::cos(nt_im);
        nt_im = std::sin(nt_im);
      }
      i = (nfft - k) - 2;
      wwc[i].re = nt_re;
      wwc[i].im = -nt_im;
    }
    i = nInt2m1 - 1;
    for (int k{i}; k >= nfft; k--) {
      wwc[k] = wwc[(nInt2m1 - k) - 1];
    }
  }
  y.set_size(nfft);
  if (nfft > x.size(0)) {
    y.set_size(nfft);
    for (i = 0; i < nfft; i++) {
      y[i].re = 0.0;
      y[i].im = 0.0;
    }
  }
  if ((n2blue != 1) && ((nfft & 1) == 0)) {
    FFTImplementationCallback::doHalfLengthBluestein(
        x, y, x.size(0), nfft, n2blue, wwc, costab, sintab, costab, sintabinv);
  } else {
    double b_re_tmp;
    double re_tmp;
    minNrowsNx = x.size(0);
    if (nfft <= minNrowsNx) {
      minNrowsNx = nfft;
    }
    for (int k{0}; k < minNrowsNx; k++) {
      nInt2m1 = (nfft + k) - 1;
      y[k].re = wwc[nInt2m1].re * x[k];
      y[k].im = wwc[nInt2m1].im * -x[k];
    }
    i = minNrowsNx + 1;
    for (int k{i}; k <= nfft; k++) {
      y[k - 1].re = 0.0;
      y[k - 1].im = 0.0;
    }
    FFTImplementationCallback::r2br_r2dit_trig_impl(y, n2blue, costab, sintab,
                                                    fv);
    FFTImplementationCallback::r2br_r2dit_trig_impl(wwc, n2blue, costab, sintab,
                                                    b_fv);
    b_fv.set_size(fv.size(0));
    minNrowsNx = fv.size(0);
    for (i = 0; i < minNrowsNx; i++) {
      nt_re = fv[i].re;
      nt_im = b_fv[i].im;
      re_tmp = fv[i].im;
      b_re_tmp = b_fv[i].re;
      b_fv[i].re = nt_re * b_re_tmp - re_tmp * nt_im;
      b_fv[i].im = nt_re * nt_im + re_tmp * b_re_tmp;
    }
    FFTImplementationCallback::r2br_r2dit_trig_impl(b_fv, n2blue, costab,
                                                    sintabinv, fv);
    if (fv.size(0) > 1) {
      nt_re = 1.0 / static_cast<double>(fv.size(0));
      minNrowsNx = fv.size(0);
      for (i = 0; i < minNrowsNx; i++) {
        fv[i].re = nt_re * fv[i].re;
        fv[i].im = nt_re * fv[i].im;
      }
    }
    i = wwc.size(0);
    for (int k{nfft}; k <= i; k++) {
      nt_re = wwc[k - 1].re;
      nt_im = fv[k - 1].im;
      re_tmp = wwc[k - 1].im;
      b_re_tmp = fv[k - 1].re;
      minNrowsNx = k - nfft;
      y[minNrowsNx].re = nt_re * b_re_tmp + re_tmp * nt_im;
      y[minNrowsNx].im = nt_re * nt_im - re_tmp * b_re_tmp;
    }
  }
}

//
// Arguments    : int nRows
//                boolean_T useRadix2
//                ::coder::array<double, 2U> &costab
//                ::coder::array<double, 2U> &sintab
//                ::coder::array<double, 2U> &sintabinv
// Return Type  : void
//
void FFTImplementationCallback::generate_twiddle_tables(
    int nRows, boolean_T useRadix2, ::coder::array<double, 2U> &costab,
    ::coder::array<double, 2U> &sintab, ::coder::array<double, 2U> &sintabinv)
{
  array<double, 2U> costab1q;
  double e;
  int i;
  int n;
  int nd2;
  e = 6.2831853071795862 / static_cast<double>(nRows);
  n = nRows / 2 / 2;
  costab1q.set_size(1, n + 1);
  costab1q[0] = 1.0;
  nd2 = n / 2 - 1;
  for (int k{0}; k <= nd2; k++) {
    costab1q[k + 1] = std::cos(e * (static_cast<double>(k) + 1.0));
  }
  i = nd2 + 2;
  nd2 = n - 1;
  for (int k{i}; k <= nd2; k++) {
    costab1q[k] = std::sin(e * static_cast<double>(n - k));
  }
  costab1q[n] = 0.0;
  if (!useRadix2) {
    n = costab1q.size(1) - 1;
    nd2 = (costab1q.size(1) - 1) << 1;
    costab.set_size(1, nd2 + 1);
    sintab.set_size(1, nd2 + 1);
    costab[0] = 1.0;
    sintab[0] = 0.0;
    sintabinv.set_size(1, nd2 + 1);
    for (int k{0}; k < n; k++) {
      sintabinv[k + 1] = costab1q[(n - k) - 1];
    }
    i = costab1q.size(1);
    for (int k{i}; k <= nd2; k++) {
      sintabinv[k] = costab1q[k - n];
    }
    for (int k{0}; k < n; k++) {
      costab[k + 1] = costab1q[k + 1];
      sintab[k + 1] = -costab1q[(n - k) - 1];
    }
    i = costab1q.size(1);
    for (int k{i}; k <= nd2; k++) {
      costab[k] = -costab1q[nd2 - k];
      sintab[k] = -costab1q[k - n];
    }
  } else {
    n = costab1q.size(1) - 1;
    nd2 = (costab1q.size(1) - 1) << 1;
    costab.set_size(1, nd2 + 1);
    sintab.set_size(1, nd2 + 1);
    costab[0] = 1.0;
    sintab[0] = 0.0;
    for (int k{0}; k < n; k++) {
      costab[k + 1] = costab1q[k + 1];
      sintab[k + 1] = -costab1q[(n - k) - 1];
    }
    i = costab1q.size(1);
    for (int k{i}; k <= nd2; k++) {
      costab[k] = -costab1q[nd2 - k];
      sintab[k] = -costab1q[k - n];
    }
    sintabinv.set_size(1, 0);
  }
}

//
// Arguments    : int nfft
//                boolean_T useRadix2
//                int *n2blue
//                int *nRows
// Return Type  : void
//
void FFTImplementationCallback::get_algo_sizes(int nfft, boolean_T useRadix2,
                                               int *n2blue, int *nRows)
{
  *n2blue = 1;
  if (useRadix2) {
    *nRows = nfft;
  } else {
    if (nfft > 0) {
      int n;
      int pmax;
      n = (nfft + nfft) - 1;
      pmax = 31;
      if (n <= 1) {
        pmax = 0;
      } else {
        int pmin;
        boolean_T exitg1;
        pmin = 0;
        exitg1 = false;
        while ((!exitg1) && (pmax - pmin > 1)) {
          int k;
          int pow2p;
          k = (pmin + pmax) >> 1;
          pow2p = 1 << k;
          if (pow2p == n) {
            pmax = k;
            exitg1 = true;
          } else if (pow2p > n) {
            pmax = k;
          } else {
            pmin = k;
          }
        }
      }
      *n2blue = 1 << pmax;
    }
    *nRows = *n2blue;
  }
}

//
// Arguments    : const ::coder::array<creal_T, 1U> &x
//                int unsigned_nRows
//                const ::coder::array<double, 2U> &costab
//                const ::coder::array<double, 2U> &sintab
//                ::coder::array<creal_T, 1U> &y
// Return Type  : void
//
void FFTImplementationCallback::r2br_r2dit_trig_impl(
    const ::coder::array<creal_T, 1U> &x, int unsigned_nRows,
    const ::coder::array<double, 2U> &costab,
    const ::coder::array<double, 2U> &sintab, ::coder::array<creal_T, 1U> &y)
{
  double temp_im;
  double temp_re;
  double temp_re_tmp;
  double twid_re;
  int i;
  int iDelta2;
  int iheight;
  int iy;
  int ju;
  int k;
  int nRowsD2;
  y.set_size(unsigned_nRows);
  if (unsigned_nRows > x.size(0)) {
    y.set_size(unsigned_nRows);
    for (iy = 0; iy < unsigned_nRows; iy++) {
      y[iy].re = 0.0;
      y[iy].im = 0.0;
    }
  }
  iDelta2 = x.size(0);
  if (iDelta2 > unsigned_nRows) {
    iDelta2 = unsigned_nRows;
  }
  iheight = unsigned_nRows - 2;
  nRowsD2 = unsigned_nRows / 2;
  k = nRowsD2 / 2;
  iy = 0;
  ju = 0;
  for (i = 0; i <= iDelta2 - 2; i++) {
    boolean_T tst;
    y[iy] = x[i];
    iy = unsigned_nRows;
    tst = true;
    while (tst) {
      iy >>= 1;
      ju ^= iy;
      tst = ((ju & iy) == 0);
    }
    iy = ju;
  }
  y[iy] = x[iDelta2 - 1];
  if (unsigned_nRows > 1) {
    for (i = 0; i <= iheight; i += 2) {
      temp_re_tmp = y[i + 1].re;
      temp_im = y[i + 1].im;
      temp_re = y[i].re;
      twid_re = y[i].im;
      y[i + 1].re = temp_re - temp_re_tmp;
      y[i + 1].im = twid_re - temp_im;
      y[i].re = temp_re + temp_re_tmp;
      y[i].im = twid_re + temp_im;
    }
  }
  iy = 2;
  iDelta2 = 4;
  iheight = ((k - 1) << 2) + 1;
  while (k > 0) {
    int b_temp_re_tmp;
    for (i = 0; i < iheight; i += iDelta2) {
      b_temp_re_tmp = i + iy;
      temp_re = y[b_temp_re_tmp].re;
      temp_im = y[b_temp_re_tmp].im;
      y[b_temp_re_tmp].re = y[i].re - temp_re;
      y[b_temp_re_tmp].im = y[i].im - temp_im;
      y[i].re = y[i].re + temp_re;
      y[i].im = y[i].im + temp_im;
    }
    ju = 1;
    for (int j{k}; j < nRowsD2; j += k) {
      double twid_im;
      int ihi;
      twid_re = costab[j];
      twid_im = sintab[j];
      i = ju;
      ihi = ju + iheight;
      while (i < ihi) {
        b_temp_re_tmp = i + iy;
        temp_re_tmp = y[b_temp_re_tmp].im;
        temp_im = y[b_temp_re_tmp].re;
        temp_re = twid_re * temp_im - twid_im * temp_re_tmp;
        temp_im = twid_re * temp_re_tmp + twid_im * temp_im;
        y[b_temp_re_tmp].re = y[i].re - temp_re;
        y[b_temp_re_tmp].im = y[i].im - temp_im;
        y[i].re = y[i].re + temp_re;
        y[i].im = y[i].im + temp_im;
        i += iDelta2;
      }
      ju++;
    }
    k /= 2;
    iy = iDelta2;
    iDelta2 += iDelta2;
    iheight -= iy;
  }
}

} // namespace internal
} // namespace coder

//
// File trailer for FFTImplementationCallback.cpp
//
// [EOF]
//
